home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 3_1_3 / sys / amiga / winfuncs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-07  |  40.0 KB  |  1,699 lines

  1. /*    SCCS Id: @(#)winfuncs.c    3.1    93/04/02 */
  2. /* Copyright (c) Gregg Wonderly, Naperville, Illinois,  1991,1992,1993. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "amiga:windefs.h"
  6. #include "amiga:winext.h"
  7. #include "amiga:winproto.h"
  8. #include "incl:patchlevel.h"
  9.  
  10. int topl_addspace=1;
  11. extern struct TagItem scrntags[];
  12.  
  13. void
  14. amii_destroy_nhwindow(win)      /* just hide */
  15.     register winid win;
  16. {
  17.     register struct amii_WinDesc *cw;
  18.  
  19.     if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
  20.     {
  21.     panic(winpanicstr,win,"destroy_nhwindow");
  22.     }
  23.  
  24. #ifdef    VIEWWINDOW
  25.     if( cw->type == NHW_MAP )
  26.     {
  27.     amii_destroy_nhwindow( WIN_VIEW );
  28.     amii_destroy_nhwindow( WIN_VIEWBOX );
  29.  
  30.     /* If inventory is up, close it now, it will be freed later */
  31.     if( alwaysinvent && WIN_INVEN != WIN_ERR &&
  32.                 amii_wins[ WIN_INVEN ] &&
  33.                 amii_wins[ WIN_INVEN ]->win )
  34.     {
  35.         dismiss_nhwindow( WIN_INVEN );
  36.     }
  37.     }
  38. #endif
  39.  
  40.     /* Tear down the Intuition stuff */
  41.     dismiss_nhwindow(win);
  42.  
  43.     if( cw->resp )
  44.     free( cw->resp );
  45.     cw->resp = NULL;
  46.  
  47.     if( cw->canresp )
  48.     free( cw->canresp );
  49.     cw->canresp = NULL;
  50.  
  51.     if( cw->morestr )
  52.     free( cw->morestr );
  53.     cw->morestr = NULL;
  54.  
  55.     free( cw );
  56.     amii_wins[win] = NULL;
  57. }
  58.  
  59. amii_create_nhwindow(type)
  60.     register int type;
  61. {
  62.     register struct Window *w = NULL;
  63.     register struct NewWindow *nw = NULL;
  64.     register struct amii_WinDesc *wd = NULL;
  65.     struct Window *mapwin = NULL, *stwin = NULL, *msgwin = NULL;
  66.     register int newid;
  67.     int maph;
  68.  
  69.     maph = ( 22 * MAPFTHEIGHT ) + HackScreen->WBorTop +
  70.             HackScreen->WBorBottom + MAPFTHEIGHT + 1 + 1;
  71.     if( WIN_STATUS != WIN_ERR && amii_wins[ WIN_STATUS ] )
  72.     stwin = amii_wins[ WIN_STATUS ]->win;
  73.  
  74.     if( WIN_MESSAGE != WIN_ERR && amii_wins[ WIN_MESSAGE ] )
  75.     msgwin = amii_wins[ WIN_MESSAGE ]->win;
  76.  
  77.     if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
  78.     mapwin = amii_wins[ WIN_MAP ]->win;
  79.  
  80.     /* Create Port anytime that we need it */
  81.  
  82.     if( HackPort == NULL )
  83.     {
  84.     HackPort = CreatePort( NULL, 0 );
  85.     if( !HackPort )
  86.         panic( "no memory for msg port" );
  87.     }
  88.  
  89.     nw = &new_wins[ type ].newwin;
  90.     nw->Width = amiIDisplay->xpix;
  91.     nw->Screen = HackScreen;
  92.  
  93.     nw->DetailPen = C_BLACK;
  94.     nw->BlockPen = C_WHITE;
  95.  
  96.     if( type == NHW_MAP || type == NHW_BASE )
  97.     {
  98.     nw->LeftEdge = 0;
  99.  
  100.     if(
  101. #ifndef    VIEWWINDOW
  102.         bigscreen &&
  103. #endif
  104.         type == NHW_MAP )
  105.     {
  106.         nw->Height = maph;
  107.         if( msgwin && stwin )
  108.         {
  109.         nw->TopEdge = msgwin->TopEdge + msgwin->Height +
  110.                 ((stwin->TopEdge-
  111.                 (msgwin->TopEdge + msgwin->Height)-maph))/2;
  112.         }
  113.         else
  114.         {
  115.         panic( "msgwin and stwin must open before map" );
  116.         }
  117. #ifdef    VIEWWINDOW
  118.         if( !bigscreen )
  119.         nw->Flags &= ~(BORDERLESS);
  120.         nw->Width = (MAPFTWIDTH * 80) + HackScreen->WBorLeft +
  121.                         HackScreen->WBorRight;
  122. #else
  123.         nw->Width = HackScreen->Width;
  124. #endif
  125.     }
  126.     else
  127.     {
  128.         nw->TopEdge = 1;
  129.         nw->Height = amiIDisplay->ypix - nw->TopEdge;
  130.     }
  131.     }
  132. #ifdef    VIEWWINDOW
  133.     else if( type == NHW_VIEWBOX )
  134.     {
  135.     struct Window *w = amii_wins[ NHW_MAP ]->win;
  136.  
  137.     nw->LeftEdge = w->Width;
  138.     nw->TopEdge = w->TopEdge;
  139.     nw->Width = amiIDisplay->xpix - nw->LeftEdge;
  140.     if( msgwin && stwin )
  141.     {
  142.         nw->Height = stwin->TopEdge - nw->TopEdge;
  143.     }
  144.     else
  145.     {
  146.         nw->Height = 10 * VIEWCHARHEIGHT +
  147.             w->BorderTop + w->BorderBottom;
  148.     }
  149.     nw->MaxHeight = VIEWCHARHEIGHT*24;
  150.     nw->MaxWidth = VIEWCHARWIDTH*80;
  151.     if( nw->TopEdge + nw->Height > amiIDisplay->ypix - 1 )
  152.         nw->Height = amiIDisplay->ypix - nw->TopEdge - 1;
  153.     if( !bigscreen )
  154.         nw->Flags &= ~(WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE);
  155.     }
  156.     else if( type == NHW_VIEW )
  157.     {
  158.     struct Window *vw = amii_wins[ WIN_VIEWBOX ]->win;
  159.     int i;
  160.  
  161.     nw->LeftEdge = vw->LeftEdge + vw->BorderLeft;
  162.     nw->TopEdge = vw->TopEdge + vw->BorderTop;
  163.     nw->Width = amiIDisplay->xpix - nw->LeftEdge - 1 - vw->BorderRight;
  164.     nw->Height = vw->Height - vw->BorderTop - vw->BorderBottom;
  165.     nw->MaxHeight = VIEWCHARHEIGHT*24;
  166.     nw->MaxWidth = VIEWCHARWIDTH*80;
  167.     if( nw->TopEdge + nw->Height > amiIDisplay->ypix - 1 )
  168.         nw->Height = amiIDisplay->ypix - nw->TopEdge - 1;
  169.     InitBitMap( &amii_vbm, DEPTH, VIEWCHARWIDTH * 88, VIEWCHARHEIGHT * 30 );
  170.     for( i = 0; i < DEPTH; ++i )
  171.     {
  172.         if( ( amii_vbm.Planes[i] = AllocRaster( VIEWCHARWIDTH * 88,
  173.                             VIEWCHARHEIGHT * 30 ) ) == 0 )
  174.         {
  175.         panic( "can't allocate bitmap for view window" );
  176.         }
  177.         memset( amii_vbm.Planes[i], 0,
  178.                     RASSIZE( VIEWCHARWIDTH * 88, VIEWCHARHEIGHT * 30 ) );
  179.     }
  180.     nw->Flags |= SUPER_BITMAP;
  181.     nw->BitMap = &amii_vbm;
  182.     }
  183. #endif
  184.     else if( type == NHW_STATUS )
  185.     {
  186. #ifndef    VIEWWINDOW
  187.     if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
  188.         w = amii_wins[ WIN_MAP ]->win;
  189.     else
  190. #endif
  191.     if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
  192.         w = amii_wins[ WIN_BASE ]->win;
  193.     else
  194.         panic( "No window to base STATUS location from" );
  195.  
  196.     /* Status window is relative to bottom of WIN_BASE/WIN_MAP */
  197.  
  198.     /* Expand the height of window by borders */
  199.     nw->Height = (txheight * 2) + 4;
  200.     if( bigscreen )
  201.     {
  202.         nw->Height += txheight + w->WScreen->WBorTop + 1 + w->WScreen->WBorBottom;
  203.     }
  204.  
  205.     nw->TopEdge = amiIDisplay->ypix - nw->Height - 1;
  206.     nw->LeftEdge = w->LeftEdge;
  207.     if( nw->LeftEdge + nw->Width >= amiIDisplay->xpix )
  208.         nw->LeftEdge = 0;
  209.     if( nw->Width >= amiIDisplay->xpix - nw->LeftEdge )
  210.         nw->Width = amiIDisplay->xpix - nw->LeftEdge;
  211.     }
  212.     else if( type == NHW_MESSAGE )
  213.     {
  214. #ifndef    VIEWWINDOW
  215.     if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
  216.         w = amii_wins[ WIN_MAP ]->win;
  217.     else
  218. #endif
  219.     if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
  220.         w = amii_wins[ WIN_BASE ]->win;
  221.     else
  222.         panic( "No window to base STATUS location from" );
  223.  
  224.     nw->TopEdge = 1;
  225.     nw->Height = HackScreen->WBorTop + 1 +
  226.         ((txheight+1)*(1+(scrollmsg != 0))) + 1 + HackScreen->WBorBottom;
  227.     if( ( HackScreen->Height - 1 -
  228.         ( ( TextsFont->tf_YSize +
  229.             HackScreen->WBorTop + 1 + HackScreen->WBorBottom ) * 2 ) -
  230.         ( ( TextsFont->tf_YSize + 1 ) * 2 ) - 2 ) - maph <
  231.             TextsFont->tf_YSize + 3 )
  232.     {
  233.         scrollmsg = 0;
  234.     }
  235.     if( scrollmsg )
  236.     {
  237.         nw->FirstGadget = &MsgScroll;
  238.         nw->Height = HackScreen->Height - 1 -
  239.         /* Size of all borders for bigscreen */
  240.         ( ( TextsFont->tf_YSize + HackScreen->WBorTop + 1 +
  241.                     HackScreen->WBorBottom ) * 2 ) -
  242.         /* Text space in status window */
  243.         ( ( TextsFont->tf_YSize + 1 ) * 2 ) - 2 -
  244.         maph;
  245.         nw->Flags |= WINDOWSIZING|WINDOWDRAG;
  246.     }
  247. #ifdef  INTUI_NEW_LOOK
  248.     if( IntuitionBase->LibNode.lib_Version >= 37 )
  249.     {
  250.         MsgPropScroll.Flags |= PROPNEWLOOK;
  251.     }
  252. #endif
  253.     /* Just allow height adjustments */
  254.     nw->MinWidth = w->Width;
  255.     nw->MinHeight = HackScreen->WBorTop +
  256.         HackScreen->WBorBottom + ((TextsFont->tf_YSize+1)*2) + 3;
  257.     }
  258.  
  259.     nw->IDCMPFlags |= MENUPICK;
  260.  
  261.     /* Check if there is "Room" for all this stuff... */
  262.     if( bigscreen && type != NHW_BASE && type != NHW_VIEW )
  263.     {
  264.     nw->Flags &= ~( BORDERLESS | BACKDROP );
  265. #ifdef    VIEWWINDOW
  266.     nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT );
  267. #else
  268.     if( HackScreen->Width < 657 )
  269.     {
  270.         nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH );
  271.     }
  272.     else
  273.     {
  274.         nw->Flags |= ( WINDOWDRAG | WINDOWDEPTH | SIZEBRIGHT );
  275.         if( type == NHW_MAP )
  276.         nw->Flags |= WINDOWSIZING;
  277.     }
  278. #endif
  279.  
  280. /*#endif*/
  281. #ifdef    VIEWWINDOW
  282.     if( type == NHW_VIEWBOX )
  283.         nw->Flags |= WINDOWSIZING;
  284. #endif
  285.     }
  286.  
  287.     /* No titles on a hires only screen */
  288.     if( !bigscreen )
  289.     nw->Title = 0;
  290.  
  291.     /* Don't open MENU or TEXT windows yet */
  292.  
  293.     if( type == NHW_MENU || type == NHW_TEXT )
  294.     w = NULL;
  295.     else
  296.     w=OpenShWindow( (void *)nw );
  297.  
  298.     if( w == NULL && type != NHW_MENU && type != NHW_TEXT )
  299.     {
  300.     char buf[ 100 ];
  301.  
  302.     sprintf( buf, "nw(%d) is l: %d, t: %d, w: %d, h: %d",
  303.         type,
  304.         nw->LeftEdge, nw->TopEdge,
  305.         nw->Width, nw->Height );
  306.     raw_print( buf );
  307.     panic("bad openwin %d",type);
  308.     }
  309.  
  310.     /* Check for an empty slot */
  311.  
  312.     for(newid = 0; newid<MAXWIN + 1; newid++)
  313.     {
  314.     if(amii_wins[newid] == 0)
  315.         break;
  316.     }
  317.  
  318.     if(newid==MAXWIN+1)
  319.     panic("time to write re-alloc code\n");
  320.  
  321.     /* Set wincnt accordingly */
  322.  
  323.     if( newid > wincnt )
  324.     wincnt = newid;
  325.  
  326.     /* Do common initialization */
  327.  
  328.     wd = (struct amii_WinDesc *)alloc(sizeof(struct amii_WinDesc));
  329.     memset( wd, 0, sizeof( struct amii_WinDesc ) );
  330.     amii_wins[newid] = wd;
  331.  
  332.     wd->newwin = NULL;
  333.     wd->win = w;
  334.     wd->type = type;
  335.     wd->wflags = 0;
  336.     wd->active = FALSE;
  337.     wd->curx=wd->cury = 0;
  338.     wd->resp = wd->canresp = wd->morestr = 0;   /* CHECK THESE */
  339.     wd->maxrow = new_wins[type].maxrow;
  340.     wd->maxcol = new_wins[type].maxcol;
  341.  
  342.     if( type != NHW_TEXT && type != NHW_MENU )
  343.     {
  344.     if( TextsFont && ( type == NHW_MESSAGE || type == NHW_STATUS ) )
  345.     {
  346.         SetFont(w->RPort, TextsFont);
  347.         txheight = w->RPort->TxHeight;
  348.         txwidth = w->RPort->TxWidth;
  349.         txbaseline = w->RPort->TxBaseline;
  350.         if( type == NHW_MESSAGE )
  351.         {
  352.         if( scrollmsg )
  353.         {
  354.             WindowLimits( w, w->Width, w->BorderTop +
  355.                 w->BorderBottom +
  356.                 ((txheight+1)*3) + 1, 0, 0 );
  357.         }
  358.         else
  359.         {
  360.             WindowLimits( w, w->Width, w->BorderTop +
  361.                 w->BorderBottom +
  362.                 txheight + 2, 0, 0 );
  363.         }
  364.         }
  365.     }
  366. #ifdef HACKFONT
  367.     else if( HackFont )
  368.         SetFont(w->RPort, HackFont);
  369. #endif
  370.     wd->rows = ( w->Height - w->BorderTop -
  371.         w->BorderBottom - 2 ) / w->RPort->TxHeight;
  372.     wd->cols = ( w->Width - w->BorderLeft -
  373.         w->BorderRight - 2 ) / w->RPort->TxWidth;
  374.     }
  375.  
  376.     /* Okay, now do the individual type initialization */
  377.  
  378.     switch(type)
  379.     {
  380.     /* History lines for MESSAGE windows are stored in cw->data[?].
  381.      * maxcol and maxrow are used as cursors.  maxrow is the count
  382.      * of the number of history lines stored.  maxcol is the cursor
  383.      * to the last line that was displayed by ^P.
  384.      */
  385.     case NHW_MESSAGE:
  386.         SetMenuStrip(w, HackMenu);
  387. #ifdef    VIEWWINDOW
  388.         if(flags.msg_history<20)flags.msg_history=20;
  389. #else
  390.         if(flags.msg_history<40)flags.msg_history=40;
  391. #endif
  392.         if(flags.msg_history>400)flags.msg_history=400;
  393.         flags.window_inited=TRUE;
  394.         wd->data = (char **)alloc( flags.msg_history*sizeof( char * ) );
  395.         memset( wd->data, 0, flags.msg_history * sizeof( char * ) );
  396.         wd->maxrow = wd->maxcol = 0;
  397.         /* Indicate that we have not positioned the cursor yet */
  398.         wd->curx = -1;
  399.         break;
  400.  
  401.         /* A MENU contains a list of lines in wd->data[?].  These
  402.          * lines are created in amii_putstr() by reallocating the size
  403.          * of wd->data to hold enough (char *)'s.  wd->rows is the
  404.          * number of (char *)'s allocated.  wd->maxrow is the number
  405.          * used.  wd->maxcol is used to track how wide the menu needs
  406.          * to be.  wd->resp[x] contains the characters that correspond
  407.          * to selecting wd->data[x].  wd->resp[x] corresponds to
  408.          * wd->data[x] for any x. Elements of wd->data[?] that are not
  409.          * valid selections have the corresponding element of
  410.          * wd->resp[] set to a value of '\01';  i.e. a ^A which is
  411.          * not currently a valid keystroke for responding to any
  412.          * MENU or TEXT window.
  413.          */
  414.     case NHW_MENU:
  415.         wd->resp=(char*)alloc(256);
  416.         wd->resp[0]=0;
  417.         wd->rows = wd->maxrow = 0;
  418.         wd->cols = wd->maxcol = 0;
  419.         wd->data = NULL;
  420.         break;
  421.  
  422.         /* See the explanation of MENU above.  Except, wd->resp[] is not
  423.          * used for TEXT windows since there is no selection of a
  424.          * a line performed/allowed.  The window is always full
  425.          * screen width.
  426.          */
  427.     case NHW_TEXT:
  428.         wd->rows = wd->maxrow = 0;
  429.         wd->cols = wd->maxcol = amiIDisplay->cols;
  430.         wd->data = NULL;
  431.         wd->morestr = NULL;
  432.         break;
  433.  
  434.         /* The status window has only two lines.  These are stored in
  435.          * wd->data[], and here we allocate the space for them.
  436.          */
  437.     case NHW_STATUS:
  438.         SetMenuStrip(w, HackMenu);
  439.         /* wd->cols is the number of characters which fit across the
  440.          * screen.
  441.          */
  442.         wd->data=(char **)alloc(3*sizeof(char *));
  443.         wd->data[0] = (char *)alloc(wd->cols + 10);
  444.         wd->data[1] = (char *)alloc(wd->cols + 10);
  445.         wd->data[2] = NULL;
  446.         break;
  447.  
  448.         /* NHW_MAP does not use wd->data[] or the other text
  449.          * manipulating members of the amii_WinDesc structure.
  450.          */
  451.     case NHW_MAP:
  452.         SetMenuStrip(w, HackMenu);
  453. #ifdef    VIEWWINDOW
  454.         WIN_VIEWBOX = amii_create_nhwindow( NHW_VIEWBOX );
  455.         WIN_VIEW = amii_create_nhwindow( NHW_VIEW );
  456.         if( HackFont4 )
  457.         SetFont( w->RPort, HackFont4 );
  458. #else
  459.         if( HackFont )
  460.         SetFont( w->RPort, HackFont );
  461. #endif
  462.         break;
  463.  
  464.         /* The base window must exist until CleanUp() deletes it. */
  465.     case NHW_BASE:
  466.         SetMenuStrip(w, HackMenu);
  467.         /* Make our requesters come to our screen */
  468.         {
  469.         register struct Process *myProcess =
  470.                     (struct Process *) FindTask(NULL);
  471.         pr_WindowPtr = (struct Window *)(myProcess->pr_WindowPtr);
  472.         myProcess->pr_WindowPtr = (APTR) w;
  473.         }
  474.  
  475.         /* Need this for RawKeyConvert() */
  476.  
  477.         ConsoleIO.io_Data = (APTR) w;
  478.         ConsoleIO.io_Length = sizeof( struct Window );
  479.         ConsoleIO.io_Message.mn_ReplyPort = CreatePort(NULL, 0L);
  480.         if( OpenDevice("console.device", -1L,
  481.                 (struct IORequest *) &ConsoleIO, 0L) != 0)
  482.         {
  483.         Abort(AG_OpenDev | AO_ConsoleDev);
  484.         }
  485.  
  486.         ConsoleDevice = (struct Library *) ConsoleIO.io_Device;
  487.  
  488.         KbdBuffered = 0;
  489.  
  490. #ifdef HACKFONT
  491.         if( TextsFont )
  492.         SetFont( w->RPort, TextsFont );
  493.         else if( HackFont )
  494.         SetFont( w->RPort, HackFont );
  495. #endif
  496.         txwidth = w->RPort->TxWidth;
  497.         txheight = w->RPort->TxHeight;
  498.         txbaseline = w->RPort->TxBaseline;
  499.         break;
  500.  
  501. #ifdef    VIEWWINDOW
  502.     case NHW_VIEWBOX:
  503.         /* Position BitMap at zero, zero */
  504.         ScrollLayer( 0, w->RPort->Layer,
  505.                 -w->RPort->Layer->Scroll_X,
  506.                   -w->RPort->Layer->Scroll_Y );
  507.     case NHW_VIEW:
  508.         if( HackFont16 )
  509.         SetFont( w->RPort, HackFont16 );
  510.         wd->curx = -1;
  511.         wd->cury = -1;
  512.         SetMenuStrip(w, HackMenu);
  513.         break;
  514. #endif
  515.  
  516.     default:
  517.         panic("bad create_nhwindow( %d )\n",type);
  518.         return WIN_ERR;
  519.     }
  520.  
  521.     return( newid );
  522. }
  523.  
  524. /* Initialize the windowing environment */
  525.  
  526. void
  527. amii_init_nhwindows()
  528. {
  529.     int forcenobig = 0;
  530.  
  531.     if (HackScreen)
  532.     panic( "init_nhwindow() called twice", 0 );
  533.  
  534.     WIN_MESSAGE = WIN_ERR;
  535.     WIN_MAP = WIN_ERR;
  536.     WIN_STATUS = WIN_ERR;
  537.     WIN_INVEN = WIN_ERR;
  538.     WIN_BASE = WIN_ERR;
  539.  
  540. #ifndef    SHAREDLIB
  541.     if ( (IntuitionBase = (struct IntuitionBase *)
  542.       OpenLibrary("intuition.library", INTUITION_VERSION)) == NULL)
  543.     {
  544.     Abort(AG_OpenLib | AO_Intuition);
  545.     }
  546.  
  547.     if ( (GfxBase = (struct GfxBase *)
  548.           OpenLibrary("graphics.library", GRAPHICS_VERSION)) == NULL)
  549.     {
  550.     Abort(AG_OpenLib | AO_GraphicsLib);
  551.     }
  552.  
  553. #ifdef    VIEWWINDOW
  554.     if ( (LayersBase = (struct Library *)
  555.         OpenLibrary("layers.library", 0)) == NULL)
  556.     {
  557.     Abort(AG_OpenLib | AO_LayersLib);
  558.     }
  559. #endif
  560. #endif
  561.     amiIDisplay=(struct amii_DisplayDesc *)alloc(sizeof(struct amii_DisplayDesc));
  562.     memset( amiIDisplay, 0, sizeof( struct amii_DisplayDesc ) );
  563.  
  564.     /* Use Intuition sizes for overscan screens... */
  565.  
  566.     amiIDisplay->ypix = GfxBase->NormalDisplayRows;
  567.     amiIDisplay->xpix = GfxBase->NormalDisplayColumns;
  568.  
  569.     amiIDisplay->cols = amiIDisplay->xpix / FONTWIDTH;
  570.  
  571.     amiIDisplay->toplin=0;
  572.     amiIDisplay->rawprint=0;
  573.     amiIDisplay->lastwin=0;
  574.  
  575.     if( bigscreen == 0 )
  576.     {
  577.     if( ( GfxBase->ActiView->ViewPort->Modes & LACE ) == LACE )
  578.     {
  579.         amiIDisplay->ypix *= 2;
  580.         NewHackScreen.ViewModes |= LACE;
  581.         bigscreen = 1;
  582.     }
  583.     else if( GfxBase->NormalDisplayRows >= 270 )
  584.     {
  585.         bigscreen = 1;
  586.     }
  587.     }
  588.     else if( bigscreen == -1 )
  589.     {
  590.     bigscreen = 0;
  591.     forcenobig = 1;
  592.     }
  593.     else if( bigscreen )
  594.     {
  595.     /* If bigscreen requested and we don't have enough rows in
  596.      * noninterlaced mode, switch to interlaced...
  597.      */
  598.     if( GfxBase->NormalDisplayRows < 270 )
  599.     {
  600.         amiIDisplay->ypix *= 2;
  601.         NewHackScreen.ViewModes |= LACE;
  602.     }
  603.     }
  604.  
  605.     if( !bigscreen )
  606.     {
  607.         scrollmsg = 0;
  608.         alwaysinvent = 0;
  609.     }
  610.     amiIDisplay->rows = amiIDisplay->ypix / FONTHEIGHT;
  611.  
  612. #ifdef HACKFONT
  613.     /*
  614.      *  Load the fonts that we need.
  615.      */
  616.  
  617.     if( DiskfontBase =
  618.         OpenLibrary( "diskfont.library", DISKFONT_VERSION ) )
  619.     {
  620.     Hack80.ta_Name -= SIZEOF_DISKNAME;
  621.     HackFont = OpenDiskFont( &Hack80 );
  622.     Hack80.ta_Name += SIZEOF_DISKNAME;
  623.  
  624. #ifdef    VIEWWINDOW
  625.     Hack40.ta_Name -= SIZEOF_DISKNAME;
  626.     HackFont4 = OpenDiskFont( &Hack40 );
  627.     Hack40.ta_Name += SIZEOF_DISKNAME;
  628.  
  629.     Hack160.ta_Name -= SIZEOF_DISKNAME;
  630.     HackFont16 = OpenDiskFont( &Hack160 );
  631.     Hack160.ta_Name += SIZEOF_DISKNAME;
  632. #endif
  633.     /* Textsfont13 is filled in with "FONT=" settings. The default is
  634.      * courier/13.
  635.      */
  636.     TextsFont = NULL;
  637.     if( bigscreen )
  638.         TextsFont = OpenDiskFont( &TextsFont13 );
  639.  
  640.     /* Try hack/8 for texts if no user specified font */
  641.     if( TextsFont == NULL )
  642.     {
  643.         Hack80.ta_Name -= SIZEOF_DISKNAME;
  644.         TextsFont = OpenDiskFont( &Hack80 );
  645.         Hack80.ta_Name += SIZEOF_DISKNAME;
  646.     }
  647.  
  648.     /* If no fonts, make everything topaz 8 for non-view windows.
  649.      */
  650.     if( !HackFont || !TextsFont )
  651.     {
  652.         Hack80.ta_Name = "topaz.font";
  653.         if( !HackFont )
  654.         {
  655.         HackFont = OpenFont( &Hack80 );
  656.         if( !HackFont )
  657.             panic( "Can't get a map font, topaz:8" );
  658.         }
  659.  
  660.         if( !TextsFont )
  661.         {
  662.         TextsFont = OpenFont( &Hack80 );
  663.         if( !TextsFont )
  664.             panic( "Can't open text font" );
  665.         }
  666.     }
  667. #ifdef    VIEWWINDOW
  668.     /*
  669.      * These other fonts are required for the view windows, so
  670.      * we have to "panic".
  671.      */
  672.     if( !HackFont4 || !HackFont16 )
  673.     {
  674.         panic( "Can't open all hack/4 or hack/16 font" );
  675.     }
  676. #endif
  677.     CloseLibrary(DiskfontBase);
  678.     DiskfontBase = NULL;
  679.     }
  680. #endif
  681.  
  682.     /* This is the size screen we want to open, within reason... */
  683.  
  684.     NewHackScreen.Width = max( WIDTH, amiIDisplay->xpix );
  685.     NewHackScreen.Height = max( SCREENHEIGHT, amiIDisplay->ypix );
  686.     {
  687.     static char fname[18];
  688.     sprintf(fname,"NetHack %d.%d.%d", VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL);
  689.     NewHackScreen.DefaultTitle=fname;
  690.     }
  691.     NewHackScreen.BlockPen = C_CYAN;
  692. #ifdef    INTUI_NEW_LOOK
  693.     if( IntuitionBase->LibNode.lib_Version >= 37 )
  694.     {
  695.         int i;
  696.         long modeid;
  697.     struct Screen *wbscr;
  698.  
  699.     for( i = 0; scrntags[i].ti_Tag != SA_DisplayID &&
  700.             scrntags[i].ti_Tag != TAG_DONE; ++i )
  701.     {
  702.         continue;
  703.     }
  704.  
  705.     NewHackScreen.Width = STDSCREENWIDTH;
  706.     NewHackScreen.Height = STDSCREENHEIGHT;
  707.  
  708.     if( forcenobig == 0 )
  709.     {
  710.         wbscr = LockPubScreen( "Workbench" );
  711.         if( wbscr )
  712.         modeid = GetVPModeID( &wbscr->ViewPort ); 
  713.  
  714.         if( ( wbscr != NULL ) && ( modeid != INVALID_ID ) )
  715.         {
  716.         if( wbscr->ViewPort.Modes & LACE )
  717.             NewHackScreen.ViewModes |= LACE;
  718.         UnlockPubScreen( NULL, wbscr );
  719.         if( scrntags[i].ti_Tag == SA_DisplayID )
  720.         {
  721.             scrntags[i].ti_Data = (ULONG)modeid;
  722.         }
  723.         }
  724.     }
  725.     else
  726.     {
  727.         if( scrntags[i].ti_Tag == SA_DisplayID )
  728.         {
  729.         scrntags[i].ti_Tag = TAG_IGNORE;
  730.         }
  731.     }
  732.     }
  733. #endif
  734.  
  735.     if( ( HackScreen = OpenScreen( (void *)&NewHackScreen ) ) == NULL )
  736.     Abort( AN_OpenScreen & ~AT_DeadEnd );
  737. #ifdef  INTUI_NEW_LOOK
  738.     if( IntuitionBase->LibNode.lib_Version >= 37 )
  739.     PubScreenStatus( HackScreen, 0 );
  740. #endif
  741.  
  742.     amiIDisplay->ypix = HackScreen->Height;
  743.     amiIDisplay->xpix = HackScreen->Width;
  744.  
  745. #ifdef TEXTCOLOR
  746.     LoadRGB4(&HackScreen->ViewPort, flags.amii_curmap, 1L << DEPTH );
  747. #endif
  748.  
  749.     /* Display the copyright etc... */
  750.  
  751.     if( WIN_BASE == WIN_ERR )
  752.     WIN_BASE = amii_create_nhwindow( NHW_BASE );
  753.     amii_clear_nhwindow( WIN_BASE );
  754.     amii_putstr( WIN_BASE, 0, "" );
  755.     amii_putstr( WIN_BASE, 0, "" );
  756.     amii_putstr( WIN_BASE, 0, "" );
  757.     amii_putstr( WIN_BASE, 0,
  758.       "NetHack, Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993.");
  759.     amii_putstr( WIN_BASE, 0,
  760.     "         By Stichting Mathematisch Centrum and M. Stephenson.");
  761.     amii_putstr( WIN_BASE, 0, "         See license for details.");
  762.     amii_putstr( WIN_BASE, 0, "");
  763.  
  764.     Initialized = 1;
  765. }
  766.  
  767. /* Clear the indicated window */
  768.  
  769. void
  770. amii_clear_nhwindow(win)
  771.     register winid win;
  772. {
  773.     register struct amii_WinDesc *cw;
  774.     register struct Window *w;
  775.  
  776.     if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
  777.     panic( winpanicstr, win, "clear_nhwindow" );
  778.  
  779.     if( w = cw->win )
  780.     SetDrMd( w->RPort, JAM2);
  781.  
  782.     cursor_off( win );
  783.  
  784.     /* should be: clear the rastport, reset x,y etc */
  785.  
  786.     if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
  787.     {
  788.     /* Window might not be opened yet */
  789.  
  790.     if( w )
  791.     {
  792.         SetAPen( w->RPort, 0 );
  793.         SetBPen( w->RPort, 0 );
  794.         RectFill( w->RPort, w->BorderLeft, w->BorderTop,
  795.           w->Width - w->BorderRight-1,
  796.           w->Height - w->BorderBottom-1 );
  797.         SetAPen( w->RPort, 1 );
  798.     }
  799.     }
  800.     else if( w )
  801.     {
  802.     if( cw->type == NHW_MESSAGE )
  803.     {
  804.         amii_curs( win, 1, 0 );
  805.         if( !scrollmsg )
  806.         TextSpaces( w->RPort, cw->cols );
  807.     }
  808.     else
  809.     {
  810.         SetAPen( w->RPort, 0 );
  811.         SetBPen( w->RPort, 0 );
  812.         RectFill( w->RPort, w->BorderLeft, w->BorderTop,
  813.           w->Width - w->BorderRight-1,
  814.           w->Height - w->BorderBottom-1 );
  815.         SetAPen( w->RPort, 1 );
  816. #ifdef    VIEWWINDOW
  817.         if( win == WIN_MAP )
  818.         amii_clear_nhwindow( WIN_VIEW );
  819. #endif
  820.     }
  821.     }
  822.  
  823.     cw->cury = 0;
  824.     cw->curx = 0;
  825.     amii_curs( win, 1, 0 );
  826. }
  827.  
  828. /* Dismiss the window from the screen */
  829.  
  830. void
  831. dismiss_nhwindow(win)
  832.     register winid win;
  833. {
  834.     int i;
  835.     register struct Window *w;
  836.     register struct amii_WinDesc *cw;
  837.  
  838.     if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
  839.     {
  840.     panic(winpanicstr,win, "dismiss_nhwindow");
  841.     }
  842.  
  843.     w = cw->win;
  844.  
  845.     if( w )
  846.     {
  847.     /* All windows have this stuff attached to them. */
  848.     if( win == WIN_MAP || win == WIN_BASE ||
  849.         win == WIN_MESSAGE || win == WIN_STATUS
  850. #ifdef    VIEWWINDOW
  851.         || win == WIN_VIEW || win == WIN_VIEWBOX
  852. #endif
  853.         )
  854.     {
  855.         ClearMenuStrip( w );
  856.     }
  857.  
  858.     /* Save where user like inventory to appear */
  859.     if( win == WIN_INVEN )
  860.     {
  861.         lastinvent.MinX = w->LeftEdge;
  862.         lastinvent.MinY = w->TopEdge;
  863.         lastinvent.MaxX = w->Width;
  864.         lastinvent.MaxY = w->Height;
  865.     }
  866.  
  867.     /* Close the window */
  868.     CloseShWindow( w );
  869.     cw->win = NULL;
  870.  
  871. #ifdef    VIEWWINDOW
  872.     if( cw->type == NHW_VIEW )
  873.     {
  874.         for( i = 0; i < DEPTH; ++i )
  875.         {
  876.         FreeRaster( amii_vbm.Planes[i],
  877.             VIEWCHARWIDTH*88, VIEWCHARHEIGHT*30 );
  878.         }
  879.     }
  880. #endif
  881.  
  882.     /* Free copy of NewWindow structure for TEXT/MENU windows. */
  883.     if( cw->newwin )
  884.         FreeNewWindow( (void *)cw->newwin );
  885.     cw->newwin = NULL;
  886.     }
  887.  
  888.     if( cw->canresp )
  889.     free( cw->canresp );
  890.     cw->canresp = NULL;
  891.  
  892.     if( cw->morestr )
  893.     free( cw->morestr );
  894.     cw->morestr = NULL;
  895.  
  896.     if( cw->data && ( cw->type == NHW_MESSAGE ||
  897.                 cw->type == NHW_MENU || cw->type == NHW_TEXT ) )
  898.     {
  899.     for( i = 0; i < cw->maxrow; ++i )
  900.     {
  901.         if( cw->data[ i ] )
  902.         free( cw->data[ i ] );
  903.     }
  904.     free( cw->data );
  905.     cw->data = NULL;
  906.     }
  907.     cw->maxrow = cw->maxcol = 0;
  908. }
  909.  
  910. void
  911. amii_exit_nhwindows(str)
  912.     const char *str;
  913. {
  914.     /* Seems strange to have to do this... but we need the BASE window
  915.      * left behind...
  916.      */
  917.     kill_nhwindows( 0 );
  918.     if( str )
  919.     {
  920.     raw_print( "\n");    /* be sure we're not under the top margin */
  921.     raw_print( str );
  922.     }
  923. }
  924.  
  925. void
  926. amii_display_nhwindow(win,blocking)
  927.     winid win;
  928.     boolean blocking;
  929. {
  930.     int i;
  931.     static int lastwin = -1;
  932.     struct Window *w;
  933.     struct amii_WinDesc *cw;
  934.  
  935.     if( !Initialized )
  936.     return;
  937.     lastwin = win;
  938.  
  939.     if( win == WIN_ERR || ( cw = amii_wins[win] ) == NULL )
  940.     panic(winpanicstr,win,"display_nhwindow");
  941.  
  942.     if( cw->type == NHW_MESSAGE )
  943.     cw->wflags &= ~FLMAP_SKIP;
  944.  
  945.     if( w = cw->win )
  946.     WindowToFront( w );
  947.  
  948.     if( cw->type == NHW_MESSAGE || cw->type == NHW_STATUS )
  949.     return;
  950.  
  951.     if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
  952.     {
  953.     flush_glyph_buffer( amii_wins[ WIN_MAP ]->win );
  954.     }
  955.  
  956.     if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
  957.     {
  958.     DoMenuScroll( win, blocking );
  959.     }
  960.     else if( cw->type==NHW_MAP )
  961.     {
  962. #ifdef    VIEWWINDOW
  963.     if( IntuitionBase->LibNode.lib_Version >= 37 )
  964.     {
  965.         MoveWindowInFrontOf( amii_wins[ WIN_VIEW ]->win,
  966.                         amii_wins[ WIN_VIEWBOX ]->win );
  967.     }
  968.     else
  969.     {
  970.         WindowToFront( amii_wins[ WIN_VIEW ]->win );
  971.     }
  972.     amii_end_glyphout( WIN_VIEW );
  973. #endif
  974.     amii_end_glyphout( win );
  975.     for( i = 0; i < MAXWIN; ++i )
  976.     {
  977.         if( ( cw = amii_wins[i] ) != NULL &&
  978.         ( cw->type == NHW_STATUS || cw->type == NHW_MESSAGE ) &&
  979.         ( cw->win ) )
  980.         {
  981.         WindowToFront(cw->win);
  982.         }
  983.     }
  984.  
  985.     /* Do more if it is time... */
  986.     if( blocking == TRUE && amii_wins[ WIN_MESSAGE ]->curx )
  987.     {
  988.         outmore( amii_wins[ WIN_MESSAGE ] );
  989.     }
  990.     }
  991.  
  992. #ifdef    VIEWWINDOW
  993.     /* Pop the inventory window to the top if it is always displayed. */
  994.     if( alwaysinvent && WIN_INVEN != WIN_ERR &&
  995.             (cw = amii_wins[ WIN_INVEN ] ) && cw->win )
  996.     {
  997.     WindowToFront( cw->win );
  998.     }
  999. #endif
  1000. }
  1001.  
  1002. void
  1003. amii_curs(window, x, y)
  1004. winid window;
  1005. register int x, y;  /* not xchar: perhaps xchar is unsigned and
  1006.            curx-x would be unsigned as well */
  1007. {
  1008.     register struct amii_WinDesc *cw;
  1009.     register struct Window *w;
  1010.     register struct RastPort *rp;
  1011.  
  1012.     if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
  1013.     panic(winpanicstr,  window, "curs");
  1014.     if( (w = cw->win) == NULL )
  1015.     {
  1016.     if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
  1017.         return;
  1018.     else
  1019.         panic( "No window open yet in curs() for winid %d\n", window );
  1020.     }
  1021.     amiIDisplay->lastwin = window;
  1022.  
  1023.     /* Make sure x is within bounds */
  1024.     if( x > 0 )
  1025.     --x;    /* column 0 is never used */
  1026.     else
  1027.     x = 0;
  1028.  
  1029.     cw->curx = x;
  1030.     cw->cury = y;
  1031. #ifdef DEBUG
  1032.     if( x<0 || y<0 || y >= cw->rows || x >= cw->cols )
  1033.     {
  1034.     char *s = "[unknown type]";
  1035.     switch(cw->type)
  1036.     {
  1037.         case NHW_MESSAGE: s = "[topl window]"; break;
  1038.         case NHW_STATUS: s = "[status window]"; break;
  1039.         case NHW_MAP: s = "[map window]"; break;
  1040.         case NHW_MENU: s = "[menu window]"; break;
  1041.         case NHW_TEXT: s = "[text window]"; break;
  1042.     }
  1043.     impossible("bad curs positioning win %d %s (%d,%d)", window, s, x, y);
  1044.     return;
  1045.     }
  1046. #endif
  1047.  
  1048. #ifdef CLIPPING
  1049.     if(clipping && window == WIN_MAP)
  1050.     {
  1051.     x -= clipx;
  1052.     y -= clipy;
  1053.     }
  1054. #endif
  1055.  
  1056.     /* Output all saved output before doing cursor movements for MAP */
  1057.  
  1058.     if( cw->type == NHW_MAP )
  1059.     {
  1060.     flush_glyph_buffer( w );
  1061. #ifdef    VIEWWINDOW
  1062.     flush_glyph_buffer( amii_wins[ WIN_VIEW ]->win );
  1063. #endif
  1064.     }
  1065.  
  1066.     /* Actually do it */
  1067.  
  1068.     rp = w->RPort;
  1069.     if( cw->type == NHW_MENU || cw->type == NHW_TEXT )
  1070.     {
  1071.     Move( rp, (x * rp->TxWidth) + w->BorderLeft + 1,
  1072.         (y*rp->TxHeight ) + rp->TxBaseline + w->BorderTop + 1 );
  1073.     }
  1074.     else if( cw->type == NHW_MAP || cw->type == NHW_BASE
  1075. #ifdef    VIEWWINDOW
  1076.     || cw->type == NHW_VIEW
  1077. #endif
  1078.     )
  1079.     {
  1080.     /* These coordinate calculations must be synced with those
  1081.      * in flush_glyph_buffer() in amiwind.c.  curs_on_u() will
  1082.      * use this code, all other drawing occurs through the glyph
  1083.      * code.  In order for the cursor to appear on top of the hero,
  1084.      * the code must compute X,Y in the same manner relative to
  1085.      * the RastPort coordinates.
  1086.      *
  1087.      * y = w->BorderTop + (g_nodes[i].y-1) * rp->TxHeight +
  1088.      *   rp->TxBaseline + 1;
  1089.      * x = g_nodes[i].x * rp->TxWidth + w->BorderLeft;
  1090.      */
  1091.  
  1092.     Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft,
  1093.             w->BorderTop + ( (y + 1) * w->RPort->TxHeight ) +
  1094.             w->RPort->TxBaseline + 1 );
  1095.     }
  1096.     else if( cw->type == NHW_MESSAGE && !scrollmsg )
  1097.     {
  1098.     Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
  1099.             w->BorderTop + w->RPort->TxBaseline + 3 );
  1100.     }
  1101.     else if( cw->type == NHW_STATUS )
  1102.     {
  1103.     Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
  1104.             (y*(w->RPort->TxHeight+1)) + w->BorderTop +
  1105.             w->RPort->TxBaseline + 1 );
  1106.     }
  1107.     else
  1108.     {
  1109.     Move( rp, (x * w->RPort->TxWidth) + w->BorderLeft + 2,
  1110.             (y*w->RPort->TxHeight) + w->BorderTop +
  1111.             w->RPort->TxBaseline + 1 );
  1112.     }
  1113. }
  1114.  
  1115. void
  1116. amii_set_text_font( name, size )
  1117.     char *name;
  1118.     int size;
  1119. {
  1120.     register int i;
  1121.     register struct amii_WinDesc *cw;
  1122.     int osize = TextsFont13.ta_YSize;
  1123.     static char nname[ 100 ];
  1124.  
  1125.     strncpy( nname, name, sizeof( nname ) - 1 );
  1126.     nname[ sizeof( nname ) - 1 ] = 0;
  1127.  
  1128.     TextsFont13.ta_Name = nname;
  1129.     TextsFont13.ta_YSize = size;
  1130.  
  1131.     /* No alternate text font allowed for 640x269 or smaller */
  1132.     if( !HackScreen || !bigscreen )
  1133.     return;
  1134.  
  1135.     /* Look for windows to set, and change them */
  1136.  
  1137.     if( DiskfontBase =
  1138.         OpenLibrary( "diskfont.library", DISKFONT_VERSION ) )
  1139.     {
  1140.     TextsFont = OpenDiskFont( &TextsFont13 );
  1141.     for( i = 0; TextsFont && i < MAXWIN; ++i )
  1142.     {
  1143.         if( (cw = amii_wins[ i ]) && cw->win != NULL )
  1144.         {
  1145.             switch( cw->type )
  1146.             {
  1147.             case NHW_STATUS:
  1148.             MoveWindow( cw->win, 0, -( size - osize ) * 2 );
  1149.             SizeWindow( cw->win, 0, ( size - osize ) * 2 );
  1150.             SetFont( cw->win->RPort, TextsFont );
  1151.             break;
  1152.             case NHW_MESSAGE:
  1153.             case NHW_MAP:
  1154.             case NHW_BASE:
  1155.             SetFont( cw->win->RPort, TextsFont );
  1156.             break;
  1157.             }
  1158.         }
  1159.     }
  1160.     }
  1161.     CloseLibrary(DiskfontBase);
  1162.     DiskfontBase = NULL;
  1163. }
  1164.  
  1165. void
  1166. kill_nhwindows( all )
  1167.     register int all;
  1168. {
  1169.     register int i;
  1170.     register struct amii_WinDesc *cw;
  1171.  
  1172.     /* Foreach open window in all of amii_wins[], CloseShWindow, free memory */
  1173.  
  1174.     for( i = 0; i < MAXWIN; ++i )
  1175.     {
  1176.     if( (cw = amii_wins[ i ]) && (cw->type != NHW_BASE || all) )
  1177.     {
  1178.         amii_destroy_nhwindow( i );
  1179.     }
  1180.     }
  1181. }
  1182.  
  1183. void
  1184. amii_cl_end( cw, i )
  1185.     register struct amii_WinDesc *cw;
  1186.     register int i;
  1187. {
  1188.     register struct Window *w = cw->win;
  1189.     register int oy, ox;
  1190.  
  1191.     if( !w )
  1192.     panic("NULL window pointer in amii_cl_end()");
  1193.  
  1194.     oy = w->RPort->cp_y;
  1195.     ox = w->RPort->cp_x;
  1196.  
  1197.     TextSpaces( w->RPort, cw->cols - i );
  1198.  
  1199.     Move( w->RPort, ox, oy );
  1200. }
  1201.  
  1202. void
  1203. cursor_off( window )
  1204.     winid window;
  1205. {
  1206.     register struct amii_WinDesc *cw;
  1207.     register struct Window *w;
  1208.     register struct RastPort *rp;
  1209.     int curx, cury;
  1210.     long dmode;
  1211.     short apen, bpen;
  1212.     unsigned char ch;
  1213.  
  1214.     if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
  1215.     {
  1216.     flags.window_inited=0;
  1217.     panic(winpanicstr,window, "cursor_off");
  1218.     }
  1219.  
  1220.     if( !(cw->wflags & FLMAP_CURSUP ) )
  1221.     return;
  1222.     w = cw->win;
  1223.  
  1224.     if( !w )
  1225.     return;
  1226.  
  1227.     cw->wflags &= ~FLMAP_CURSUP;
  1228.     rp = w->RPort;
  1229.  
  1230.     /* Save the current information */
  1231.     curx = rp->cp_x;
  1232.     cury = rp->cp_y;
  1233.     dmode = rp->DrawMode;
  1234.     apen = rp->FgPen;
  1235.     bpen = rp->BgPen;
  1236.     SetAPen( rp, cw->curs_apen );
  1237.     SetBPen( rp, cw->curs_bpen );
  1238.     SetDrMd( rp, COMPLEMENT );
  1239.  
  1240.     ch = CURSOR_CHAR;
  1241.     Move( rp, cw->cursx, cw->cursy );
  1242.     Text( rp, &ch, 1 );
  1243.  
  1244. #ifdef    VIEWWINDOW
  1245.     /* Remove view window outline from map */
  1246.     if( window == WIN_MAP )
  1247.     {
  1248.     SetAPen( rp, C_RED );
  1249.     SetBPen( rp, C_BLACK );
  1250.     SetDrMd( rp, COMPLEMENT );
  1251.         Move( rp, cw->vwx, cw->vwy );
  1252.         Draw( rp, cw->vcx, cw->vwy );
  1253.         Draw( rp, cw->vcx, cw->vcy );
  1254.         Draw( rp, cw->vwx, cw->vcy );
  1255.         Draw( rp, cw->vwx, cw->vwy );
  1256.     }
  1257. #endif
  1258.  
  1259.     /* Put back the other stuff */
  1260.  
  1261.     Move( rp, curx, cury );
  1262.     SetDrMd( rp, dmode );
  1263.     SetAPen( rp, apen );
  1264.     SetBPen( rp, bpen );
  1265.  
  1266. #ifdef    VIEWWINDOW
  1267.     if( window == WIN_MAP )
  1268.     cursor_off( WIN_VIEW );
  1269. #endif
  1270. }
  1271.  
  1272. void
  1273. cursor_on( window )
  1274.     winid window;
  1275. {
  1276.     register struct amii_WinDesc *cw;
  1277.     register struct Window *w;
  1278. #ifdef    VIEWWINDOW
  1279.     int deltax, deltay, modx, mody;
  1280.     register struct amii_WinDesc *vcw;
  1281.     register struct Window *vw;
  1282. #endif
  1283.     register struct RastPort *rp;
  1284.     unsigned char ch;
  1285.     long dmode;
  1286.     short apen, bpen;
  1287.  
  1288.     if( window == WIN_ERR || ( cw = amii_wins[window] ) == NULL )
  1289.     {
  1290.     /* tty does this differently - is this OK? */
  1291.     flags.window_inited=0;
  1292.     panic(winpanicstr,window, "cursor_on");
  1293.     }
  1294.  
  1295.     if( (cw->wflags & FLMAP_CURSUP ) )
  1296.     cursor_off( window );
  1297.  
  1298.     w = cw->win;
  1299.  
  1300.     if( !w )
  1301.     return;
  1302.  
  1303.     cw->wflags |= FLMAP_CURSUP;
  1304.     rp = w->RPort;
  1305.  
  1306.     /* Save the current information */
  1307.  
  1308.     cw->cursx = rp->cp_x;
  1309.     cw->cursy = rp->cp_y;
  1310.     apen = rp->FgPen;
  1311.     bpen = rp->BgPen;
  1312.     dmode = rp->DrawMode;
  1313.     ch = CURSOR_CHAR;
  1314.  
  1315.     /* Draw in complement mode. The cursor body will be C_WHITE */
  1316.  
  1317.     cw->curs_apen = C_WHITE;
  1318.     cw->curs_bpen = C_WHITE;
  1319.     SetAPen( rp, cw->curs_apen );
  1320.     SetBPen( rp, cw->curs_bpen );
  1321.     SetDrMd( rp, COMPLEMENT );
  1322.     Move( rp, cw->cursx, cw->cursy );
  1323.     Text( rp, &ch, 1 );
  1324.     Move( rp, cw->cursx, cw->cursy );
  1325.  
  1326. #ifdef    VIEWWINDOW
  1327.     if( window == WIN_MAP )
  1328.     {
  1329.         int x, y, cx, cy;
  1330.  
  1331.     if( WIN_VIEW == WIN_ERR || ( vcw = amii_wins[ WIN_VIEW ] ) == NULL )
  1332.     {
  1333.         flags.window_inited=0;
  1334.         panic(winpanicstr,WIN_VIEW, "cursor_on");
  1335.     }
  1336.  
  1337.     if( (vcw->wflags & FLMAP_CURSUP ) )
  1338.         cursor_off( WIN_VIEW );
  1339.  
  1340.     vw = vcw->win;
  1341.  
  1342.         x = cw->cursx - (vw->Width/8);
  1343.     if( x <= w->BorderLeft )
  1344.         x = w->BorderLeft + 1;
  1345.  
  1346.         y = cw->cursy - (vw->Height/8);
  1347.     if( y <= w->BorderTop )
  1348.         y = w->BorderTop + 1;
  1349.  
  1350.     cx = x + (vw->Width/4);
  1351.     if( cx >= w->Width - w->BorderRight )
  1352.     {
  1353.         cx = w->Width - w->BorderRight-1;
  1354.         x = cx - (vw->Width/4);
  1355.     }
  1356.  
  1357.     cy = y + (vw->Height/4);
  1358.     if( cy >= w->Height - w->BorderBottom )
  1359.     {
  1360.         cy = w->Height - w->BorderBottom-1;
  1361.         y = cy - (vw->Height/4);
  1362.     }
  1363.     cw->vwx = x;
  1364.     cw->vwy = y;
  1365.     cw->vcx = cx;
  1366.     cw->vcy = cy;
  1367.     SetAPen( rp, C_RED );
  1368.     SetBPen( rp, C_BLACK );
  1369.     SetDrMd( rp, COMPLEMENT );
  1370.         Move( rp, cw->vwx, cw->vwy );
  1371.         Draw( rp, cw->vcx, cw->vwy );
  1372.         Draw( rp, cw->vcx, cw->vcy );
  1373.         Draw( rp, cw->vwx, cw->vcy );
  1374.         Draw( rp, cw->vwx, cw->vwy );
  1375.  
  1376.     /* Position VIEW at same location as cursor in MAP */
  1377.     vcw->curx  = ( cw->cursx * 4 ) - (vw->Width/2) - vw->RPort->Layer->Scroll_X;
  1378.     vcw->cury  = ( cw->cursy * 4 ) - ((2*vw->Height)/3) - vw->RPort->Layer->Scroll_Y;
  1379.  
  1380.     if( vcw->curx + vw->RPort->Layer->Scroll_X < 0 )
  1381.         vcw->curx = -vw->RPort->Layer->Scroll_X;
  1382.     else if( vcw->curx + vw->RPort->Layer->Scroll_X > vw->RPort->Layer->bounds.MaxX )
  1383.         vcw->curx = vw->RPort->Layer->bounds.MaxX - vw->RPort->Layer->Scroll_X;
  1384.  
  1385.     if( vcw->cury + vw->RPort->Layer->Scroll_Y < 0 )
  1386.         vcw->cury = -vw->RPort->Layer->Scroll_Y;
  1387.     else if( vcw->cury + vw->RPort->Layer->Scroll_Y > vw->RPort->Layer->bounds.MaxY )
  1388.         vcw->cury = vw->RPort->Layer->bounds.MaxY - vw->RPort->Layer->Scroll_Y;
  1389.  
  1390.     {
  1391.         char buf[ 100 ];
  1392.         sprintf( buf, "bounds: %d,%d,%d,%d",
  1393.             vw->RPort->Layer->bounds.MinX,
  1394.             vw->RPort->Layer->bounds.MinY,
  1395.             vw->RPort->Layer->bounds.MaxX,
  1396.             vw->RPort->Layer->bounds.MaxY );
  1397.         putstr( WIN_MESSAGE, 1, buf );
  1398.         sprintf( buf, "loc - old: %d,%d,  new: %d,%d",
  1399.             vw->RPort->Layer->Scroll_X,
  1400.             vw->RPort->Layer->Scroll_Y,
  1401.             vcw->curx + vw->RPort->Layer->Scroll_X,
  1402.             vw->RPort->Layer->Scroll_Y + vcw->cury );
  1403.         putstr( WIN_MESSAGE, 1, buf );
  1404.     }
  1405.  
  1406.     /* Figure out the scroll values to move in no more than 3 scrolls */
  1407.     deltax     = vcw->curx / 3;
  1408.     deltay     = vcw->cury / 3;
  1409.     modx       = vcw->curx % 3;
  1410.     mody       = vcw->cury % 3;
  1411.     vcw->curx -= modx;
  1412.     vcw->cury -= mody;
  1413.  
  1414.     while( vcw->curx != 0 || vcw->cury != 0 )
  1415.     {
  1416.         ScrollLayer( 0, vw->RPort->Layer, deltax, deltay );
  1417.         vcw->curx -= deltax;
  1418.         vcw->cury -= deltay;
  1419.     }
  1420.     if( modx || mody )
  1421.         ScrollLayer( 0, vw->RPort->Layer, modx, mody );
  1422.     }
  1423. #endif
  1424.  
  1425.     SetDrMd( rp, dmode );
  1426.     SetAPen( rp, apen );
  1427.     SetBPen( rp, bpen );
  1428. }
  1429.  
  1430. void amii_suspend_nhwindows( str )
  1431.     char *str;
  1432. {
  1433.     if( HackScreen )
  1434.     ScreenToBack( HackScreen );
  1435. }
  1436.  
  1437. void amii_resume_nhwindows()
  1438. {
  1439.     if( HackScreen )
  1440.     ScreenToFront( HackScreen );
  1441. }
  1442.  
  1443. void amii_bell()
  1444. {
  1445.     DisplayBeep( NULL );
  1446. }
  1447.  
  1448. void
  1449. removetopl(cnt)
  1450.     int cnt;
  1451. {
  1452.     struct amii_WinDesc *cw=amii_wins[WIN_MESSAGE];
  1453.                     /* NB - this is sufficient for
  1454.                      * yn_function, but that's it
  1455.                      */
  1456.     if(cw->curx < cnt)cw->curx=0;
  1457.     else cw->curx -= cnt;
  1458.  
  1459.     amii_curs(WIN_MESSAGE, cw->curx+1, 0);
  1460.     amii_cl_end(cw, cw->curx);
  1461. }
  1462. /*#endif /* AMIGA_INTUITION */
  1463.  
  1464. #ifdef  PORT_HELP
  1465. void
  1466. port_help()
  1467. {
  1468.     display_file( PORT_HELP, 1 );
  1469. }
  1470. #endif
  1471.  
  1472. /*
  1473.  *  print_glyph
  1474.  *
  1475.  *  Print the glyph to the output device.  Don't flush the output device.
  1476.  *
  1477.  *  Since this is only called from show_glyph(), it is assumed that the
  1478.  *  position and glyph are always correct (checked there)!
  1479.  */
  1480.  
  1481. void
  1482. amii_print_glyph(win,x,y,glyph)
  1483.     winid win;
  1484.     xchar x,y;
  1485.     int glyph;
  1486. {
  1487.     struct amii_WinDesc *cw;
  1488.     uchar   ch;
  1489.     register int offset;
  1490. #ifdef TEXTCOLOR
  1491.     int     color;
  1492. #ifndef    SHAREDLIB
  1493.     extern int zapcolors[];
  1494. #endif
  1495.  
  1496.     if( win == WIN_ERR || (cw=amii_wins[win]) == NULL || cw->type != NHW_MAP)
  1497.     panic(winpanicstr,win,"print_glyph");
  1498.  
  1499. #define zap_color(n)  color = flags.use_color ? zapcolors[n] : NO_COLOR
  1500. #define cmap_color(n) color = flags.use_color ? defsyms[n].color : NO_COLOR
  1501. #define trap_color(n) color = flags.use_color ? \
  1502.         (((n) == WEB) ? defsyms[S_web ].color  : \
  1503.                 defsyms[S_trap].color) : \
  1504.             NO_COLOR
  1505. #define obj_color(n)  color = flags.use_color ? objects[n].oc_color : NO_COLOR
  1506. #define mon_color(n)  color = flags.use_color ? mons[n].mcolor : NO_COLOR
  1507. #define pet_color(n)  color = flags.use_color ? mons[n].mcolor :          \
  1508.         /* If no color, try to hilite pets; black  */ \
  1509.         /* should be HI                */ \
  1510.             ((flags.hilite_pet) ? BLACK : NO_COLOR)
  1511.  
  1512. # else /* no text color */
  1513.  
  1514. #define zap_color(n)
  1515. #define cmap_color(n)
  1516. #define trap_color(n)
  1517. #define obj_color(n)
  1518. #define mon_color(n)
  1519. #define pet_color(n)
  1520.  
  1521. #endif
  1522.  
  1523.     /*
  1524.      *  Map the glyph back to a character.
  1525.      *
  1526.      *  Warning:  For speed, this makes an assumption on the order of
  1527.      *        offsets.  The order is set in display.h.
  1528.      */
  1529.     if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) {  /* swallow */
  1530.     /* see swallow_to_glyph()in display.c */
  1531.     ch = (uchar) showsyms[S_sw_tl + (offset & 0x7)];
  1532.     mon_color(offset >> 3);
  1533.     } else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) {       /* zap beam */
  1534.     ch = showsyms[S_vbeam + (offset & 0x3)];
  1535.     zap_color((offset >> 2));
  1536.     } else if( ( offset = (glyph - GLYPH_CMAP_OFF) ) >= 0 ) {   /* cmap */
  1537.     ch = showsyms[offset];
  1538.     cmap_color(offset);
  1539.     } else if ( ( offset = (glyph - GLYPH_TRAP_OFF) ) >= 0 ) {  /* trap */
  1540.     ch = (offset == WEB) ? showsyms[S_web] : showsyms[S_trap];
  1541.     trap_color(offset);
  1542.     } else if( ( offset = (glyph - GLYPH_OBJ_OFF) ) >= 0 ) {    /* object */
  1543.     ch = oc_syms[objects[offset].oc_class];
  1544.     obj_color(offset);
  1545.     } else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) {  /* a corpse */
  1546.     ch = oc_syms[objects[CORPSE].oc_class];
  1547.     mon_color(offset);
  1548.     } else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) {   /* a pet */
  1549.     ch = (uchar) monsyms[mons[offset].mlet];
  1550.     pet_color(offset);
  1551.     } else /*if( glyph_is_monster(glyph) )*/ {      /* a monster */
  1552.     ch = (uchar) monsyms[mons[glyph].mlet];
  1553.     mon_color(glyph);
  1554.     }
  1555.  
  1556.     /* Move the cursor. */
  1557. #ifdef CLIPPING
  1558.     if (!win_curs(x, y)) return;
  1559. #else
  1560.     amii_curs(win,x,y+2);
  1561. #endif
  1562.  
  1563. #ifdef TEXTCOLOR
  1564.     /* Turn off color if rogue level. */
  1565. # ifdef REINCARNATION
  1566.     if (Is_rogue_level(&u.uz))
  1567.     color = NO_COLOR;
  1568. #  endif
  1569.  
  1570.     amiga_print_glyph(win,color,ch);
  1571. #else
  1572.     g_putch(ch);    /* print the character */
  1573. #endif
  1574.     cw->curx++;     /* one character over */
  1575. }
  1576.  
  1577. /* Make sure the user sees a text string when no windowing is available */
  1578.  
  1579. void
  1580. amii_raw_print(s)
  1581.     register const char *s;
  1582. {
  1583.     if( !s )
  1584.     return;
  1585.     if(amiIDisplay)
  1586.     amiIDisplay->rawprint++;
  1587.  
  1588.     if( Initialized == 0 && WIN_BASE == WIN_ERR )
  1589.         init_nhwindows();
  1590.  
  1591.     if( amii_rawprwin != WIN_ERR )
  1592.     amii_putstr( amii_rawprwin, 0, s );
  1593.     else if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
  1594.     amii_putstr( WIN_MAP, 0, s );
  1595.     else if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
  1596.     amii_putstr( WIN_BASE, 0, s );
  1597.     else
  1598.     {
  1599.     puts( s);
  1600.     fflush(stdout);
  1601.     }
  1602. }
  1603.  
  1604. /* Make sure the user sees a bold text string when no windowing
  1605.  * is available
  1606.  */
  1607.  
  1608. void
  1609. amii_raw_print_bold(s)
  1610.     register const char *s;
  1611. {
  1612.     if( !s )
  1613.     return;
  1614.  
  1615.     if(amiIDisplay)
  1616.     amiIDisplay->rawprint++;
  1617.  
  1618.     if( Initialized == 0 && WIN_BASE == WIN_ERR )
  1619.         init_nhwindows();
  1620.  
  1621.     if( amii_rawprwin != WIN_ERR )
  1622.     amii_putstr( amii_rawprwin, 1, s );
  1623.     else if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
  1624.     amii_putstr( WIN_MAP, 1, s );
  1625.     else if( WIN_BASE != WIN_ERR && amii_wins[ WIN_BASE ] )
  1626.     amii_putstr( WIN_BASE, 1, s );
  1627.     else
  1628.     {
  1629.     printf("\33[1m%s\33[0m\n",s);
  1630.     fflush(stdout);
  1631.     }
  1632. }
  1633.  
  1634. /* Rebuild/update the inventory if the window is up.
  1635.  */
  1636. void
  1637. amii_update_inventory()
  1638. {
  1639.     register struct amii_WinDesc *cw;
  1640.  
  1641.     if( WIN_INVEN != WIN_ERR && ( cw = amii_wins[ WIN_INVEN ] ) &&
  1642.                 cw->type == NHW_MENU && cw->win )
  1643.     {
  1644.     display_inventory( NULL, FALSE );
  1645.     }
  1646. }
  1647.  
  1648. /* Humm, doesn't really do anything useful */
  1649.  
  1650. void
  1651. amii_mark_synch()
  1652. {
  1653.     if(!amiIDisplay)
  1654.     fflush(stderr);
  1655. /* anything else?  do we need this much? */
  1656. }
  1657.  
  1658. /* Wait for everything to sync.  Nothing is asynchronous, so we just
  1659.  * ask for a key to be pressed.
  1660.  */
  1661. void
  1662. amii_wait_synch()
  1663. {
  1664.     if(!amiIDisplay || amiIDisplay->rawprint)
  1665.     {
  1666.     if(amiIDisplay) amiIDisplay->rawprint=0;
  1667.     }
  1668.     else
  1669.     {
  1670.     display_nhwindow(WIN_MAP,TRUE);
  1671.     flush_glyph_buffer( amii_wins[ WIN_MAP ]->win );
  1672.     }
  1673. }
  1674.  
  1675. void
  1676. amii_setclipped()
  1677. {
  1678.     clipping = TRUE;
  1679.     clipx=clipy=0;
  1680.     clipxmax=CO;        /* WRONG */
  1681.     clipymax=LI-5;      /* WRONG */
  1682. }
  1683.  
  1684. void
  1685. amii_cliparound(x,y)
  1686.     register int x,y;
  1687. {
  1688. /* pull this from wintty.c - LATER */
  1689. }
  1690.  
  1691. void
  1692. flushIDCMP( port )
  1693.     struct MsgPort *port;
  1694. {
  1695.     struct Message *msg;
  1696.     while( msg = GetMsg( port ) )
  1697.         ReplyMsg( msg );
  1698. }
  1699.